﻿#region Copyrigth and License
/*==============================================================================
 *  Copyright (c) cndotnet.org Corporation.  All rights reserved.
 * ===============================================================================
 * This code and information is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the implied warranties
 * of merchantability and fitness for a particular purpose.
 * ===============================================================================
 * Licensed under the GNU General Public License (GPL) v2
 * http://www.cndotnet.org/ezsocio
 * ==============================================================================*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using System.Web;
using System.Net;
using System.IO;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Collections;

namespace DusonFramework.ContactService
{
    public class WebOpHelper {
        #region Fields

        #endregion

        #region Constructors

        #endregion

        #region Properties

        #endregion

        #region Events

        #endregion

        #region Methods
        /// <summary>
        /// get NameValueCollection Row Data
        /// </summary>
        /// <param name="nvc"></param>
        /// <param name="separator"></param>
        public static string GetNameValueRowData(NameValueCollection nvc, char separator) {
            StringBuilder sb = new StringBuilder();
            foreach (string key in nvc.AllKeys) {
                sb.Append(key + "=" + HttpUtility.UrlEncode(nvc[key]) + separator.ToString());
            }
            return sb.ToString().TrimEnd(separator);
        }
        public static string GetRegExParsedValue(string strPattern, string strSearch) {
            Regex reg = new Regex(strPattern, RegexOptions.Multiline);
            Match mat = reg.Match(strSearch);
            if (mat.Success) {
                return mat.Groups["RetVal"].Value.ToString();
            }
            return string.Empty;
        }

        /// <summary>
        /// Get Content of one page by GET Mothod
        /// </summary>
        /// <param name="url">address of page</param>
        /// <param name="encoding">encode or charset</param>
        /// <returns>the content of page</returns>
        public static string GetHtml(string url, string accept, string contentType, string referer, string language, CookieContainer cc, Encoding encoding, out string returnUrl) {
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);            
            req.CookieContainer = cc;
            req.Accept = accept;
            req.ContentType = contentType;
            if (!string.IsNullOrEmpty(referer)) {
                req.Referer = referer;
            }
            req.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506; .NET CLR 3.5.21022)";
            if (!string.IsNullOrEmpty(language)) {
                req.Headers.Add("Accept-Language", language);
            }
            req.Headers.Add("UA-CPU", "x86");
            req.AllowAutoRedirect = true;
            req.KeepAlive = true;
            req.Method = "GET";
            req.UseDefaultCredentials = true;
            using (var res = (HttpWebResponse)req.GetResponse()) {
                var response = res.GetResponseStream();
                if (req.CookieContainer != null) {
                    res.Cookies = req.CookieContainer.GetCookies(req.RequestUri);
                    string cks = cc.GetCookieHeader(req.RequestUri);
                    Debug.WriteLine(cks);
                }
                string responseUrl = res.ResponseUri.ToString();
                returnUrl = responseUrl;
                using (StreamReader sr = new StreamReader(response, encoding)) {
                    string content = sr.ReadToEnd();
                    //Debug.WriteLine("GetHtml of url:" + returnUrl);
                    //Debug.WriteLine(content);
                    return content;
                }
            }
        }

        public static string GetJavaScriptTime() {
            Int64 retval = 0;
            DateTime st = new DateTime(1970, 1, 1);
            TimeSpan t = (DateTime.Now - st);
            retval = (Int64)(t.TotalMilliseconds + 0.5);
            retval = retval + 1000000;
            return retval.ToString();
        }
        /// <summary>
        /// Get Content of one page by GET Mothod
        /// </summary>
        /// <param name="url">address of page</param>
        /// <param name="encoding">encode or charset</param>
        /// <returns>the content of page</returns>
        public static string GetHtml(string url, string accept, string contentType, string referer, string language, string cookies, Encoding encoding, out string returnUrl) {
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
           
            req.Accept = accept;
            req.ContentType = contentType;
            req.Referer = referer;
            req.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506; .NET CLR 3.5.21022)";
            if (!string.IsNullOrEmpty(language)) {
                req.Headers.Add("Accept-Language", language);
            }
            req.Headers.Add("UA-CPU", "x86");
            req.AllowAutoRedirect = true;
            req.Method = "GET";
            if (!string.IsNullOrEmpty(cookies)) {
                req.Headers.Add("Cookie", cookies);
            }
            
            using (var res = (HttpWebResponse)req.GetResponse()) {
                var response = res.GetResponseStream();
                if (req.CookieContainer != null) {
                    res.Cookies = req.CookieContainer.GetCookies(req.RequestUri);                  
                }
                string responseUrl = res.ResponseUri.ToString();
                returnUrl = responseUrl;
                using (StreamReader sr = new StreamReader(response, encoding)) {
                    string content = sr.ReadToEnd();
                    //Debug.WriteLine("GetHtml of url:" + returnUrl);
                    //Debug.WriteLine(content);
                    return content;
                }
            }
        }
        /// <summary>
        /// Get Content of one page by GET Mothod
        /// </summary>
        /// <param name="url">address of page</param>
        /// <param name="encoding">encode or charset</param>
        /// <returns>the content of page</returns>
        public static string Post(string url, string accept, string contentType, string referer, string language,string postContent, CookieContainer cc, Encoding encoding, out string returnUrl) {
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
            req.CookieContainer = cc;
            req.Accept = accept;
            req.ContentType = contentType;
            req.Referer = referer;
            req.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506; .NET CLR 3.5.21022)";
            if (!string.IsNullOrEmpty(language)) {
                req.Headers.Add("Accept-Language", language);
            }
            req.Headers.Add("UA-CPU", "x86");
            req.AllowAutoRedirect = true;
            req.UseDefaultCredentials = true;
            req.Method = "POST";
            if (!string.IsNullOrEmpty(postContent)) {
               using(StreamWriter sw = new StreamWriter(req.GetRequestStream(),encoding)){
                   sw.Write(postContent);
                   sw.Flush();
               }
            }
            using (var res = (HttpWebResponse)req.GetResponse()) {
                var response = res.GetResponseStream();
                if (req.CookieContainer != null) {
                    res.Cookies = req.CookieContainer.GetCookies(req.RequestUri);                   
                }
                string responseUrl = res.ResponseUri.ToString();
                returnUrl = responseUrl;
                using (StreamReader sr = new StreamReader(response, encoding)) {
                    string content = sr.ReadToEnd();
                    Debug.WriteLine("GetHtml of url:" + returnUrl);
                    Debug.WriteLine(content);
                    return content;
                }
            }
        }
        /// <summary>
        /// Get Content of one page by GET Mothod
        /// </summary>
        /// <param name="url">address of page</param>
        /// <param name="encoding">encode or charset</param>
        /// <returns>the content of page</returns>
        public static string PostNoAutoRedirect(string url, string accept, string contentType, string referer, string language, string postContent, ref CookieContainer cc, Encoding encoding, out string returnUrl) {
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
            req.CookieContainer = cc;
            req.Accept = accept;
            req.ContentType = contentType;
            req.Referer = referer;
            req.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506; .NET CLR 3.5.21022)";
            if (!string.IsNullOrEmpty(language)) {
                req.Headers.Add("Accept-Language", language);
            }
            req.Headers.Add("UA-CPU", "x86");
            req.AllowAutoRedirect = false;
            req.UseDefaultCredentials = true;
            req.Method = "POST";
            if (!string.IsNullOrEmpty(postContent)) {
                using (StreamWriter sw = new StreamWriter(req.GetRequestStream(), encoding)) {
                    sw.Write(postContent);
                    sw.Flush();
                }
            }
            using (var res = (HttpWebResponse)req.GetResponse()) {
                var response = res.GetResponseStream();
                if (req.CookieContainer != null) {
                    res.Cookies = req.CookieContainer.GetCookies(req.RequestUri);
                    var cookies = GetAllCookiesFromHeader(res.Headers["Set-Cookie"], res.ResponseUri.Host);
                    cc = new CookieContainer();
                    cc.Add(cookies);
                }
                string responseUrl = res.Headers["Location"];
                returnUrl = responseUrl;
                using (StreamReader sr = new StreamReader(response, encoding)) {
                    string content = sr.ReadToEnd();
                    Debug.WriteLine("GetHtml of url:" + returnUrl);
                    Debug.WriteLine(content);
                    return content;
                }
            }
        }
        public static string Post(string url, string accept, string contentType, string referer, string language, string postContent, ref CookieContainer cc, Encoding encoding, out string returnUrl) {
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
            req.CookieContainer = cc;
            req.Accept = accept;
            req.ContentType = contentType;
            req.Headers["Cache-Control"] = "no-cache";
            req.Referer = referer;
            req.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506; .NET CLR 3.5.21022)";
            if (!string.IsNullOrEmpty(language)) {
                req.Headers.Add("Accept-Language", language);
            }
            req.Headers.Add("UA-CPU", "x86");
            req.AllowAutoRedirect = true;
            req.UseDefaultCredentials = true;
            req.Method = "POST";
            if (!string.IsNullOrEmpty(postContent)) {
                using (StreamWriter sw = new StreamWriter(req.GetRequestStream(), encoding)) {
                    sw.Write(postContent);                    
                    sw.Flush();
                }
            }
            using (var res = (HttpWebResponse)req.GetResponse()) {
                var response = res.GetResponseStream();
                if (req.CookieContainer != null) {
                    res.Cookies = req.CookieContainer.GetCookies(req.RequestUri);
                    var cookies = GetAllCookiesFromHeader(res.Headers["Set-Cookie"], res.ResponseUri.Host);
                    cc = new CookieContainer();
                    cc.Add(cookies);
                }
                string responseUrl = res.ResponseUri.ToString();
                returnUrl = responseUrl;
                using (StreamReader sr = new StreamReader(response, encoding)) {
                    string content = sr.ReadToEnd();
                    Debug.WriteLine("GetHtml of url:" + returnUrl);
                    Debug.WriteLine(content);
                    return content;
                }
            }
        }    
        public static CookieCollection GetAllCookiesFromHeader(string strHeader, string strHost) {
            ArrayList al = new ArrayList();
            CookieCollection cc = new CookieCollection();
            if (strHeader != string.Empty) {
                al = ConvertCookieHeaderToArrayList(strHeader);
                cc = ConvertCookieArraysToCookieCollection(al, strHost);
            }
            return cc;
        }
        private static ArrayList ConvertCookieHeaderToArrayList(string strCookHeader) {
            if (string.IsNullOrEmpty(strCookHeader)) {
                return new ArrayList();
            }
            strCookHeader = strCookHeader.Replace("\r", "");
            strCookHeader = strCookHeader.Replace("\n", "");
            string[] strCookTemp = strCookHeader.Split(',');
            ArrayList al = new ArrayList();
            int i = 0;
            int n = strCookTemp.Length;
            while (i < n) {
                if (strCookTemp[i].IndexOf("expires=", StringComparison.OrdinalIgnoreCase) > 0) {
                    al.Add(strCookTemp[i] + "," + strCookTemp[i + 1]);
                    i = i + 1;
                }
                else {
                    al.Add(strCookTemp[i]);
                }
                i = i + 1;
            }
            return al;
        }

        private static CookieCollection ConvertCookieArraysToCookieCollection(ArrayList al, string strHost) {
            CookieCollection cc = new CookieCollection();

            int alcount = al.Count;
            string strEachCook;
            string[] strEachCookParts;
            for (int i = 0; i < alcount; i++) {
                strEachCook = al[i].ToString();
                strEachCookParts = strEachCook.Split(';');
                int intEachCookPartsCount = strEachCookParts.Length;
                string strCNameAndCValue = string.Empty;
                string strPNameAndPValue = string.Empty;
                string strDNameAndDValue = string.Empty;
                string[] NameValuePairTemp;
                Cookie cookTemp = new Cookie();

                for (int j = 0; j < intEachCookPartsCount; j++) {
                    if (j == 0) {
                        strCNameAndCValue = strEachCookParts[j];
                        if (strCNameAndCValue != string.Empty) {
                            int firstEqual = strCNameAndCValue.IndexOf("=");
                            string firstName = strCNameAndCValue.Substring(0, firstEqual);
                            string allValue = strCNameAndCValue.Substring(firstEqual + 1, strCNameAndCValue.Length - (firstEqual + 1));
                            cookTemp.Name = firstName;
                            cookTemp.Value = allValue;
                        }
                        continue;
                    }
                    if (strEachCookParts[j].IndexOf("path", StringComparison.OrdinalIgnoreCase) >= 0) {
                        strPNameAndPValue = strEachCookParts[j];
                        if (strPNameAndPValue != string.Empty) {
                            NameValuePairTemp = strPNameAndPValue.Split('=');
                            if (NameValuePairTemp[1] != string.Empty) {
                                cookTemp.Path = NameValuePairTemp[1];
                            }
                            else {
                                cookTemp.Path = "/";
                            }
                        }
                        continue;
                    }

                    if (strEachCookParts[j].IndexOf("domain", StringComparison.OrdinalIgnoreCase) >= 0) {
                        strPNameAndPValue = strEachCookParts[j];
                        if (strPNameAndPValue != string.Empty) {
                            NameValuePairTemp = strPNameAndPValue.Split('=');

                            if (NameValuePairTemp[1] != string.Empty) {
                                cookTemp.Domain = NameValuePairTemp[1];
                            }
                            else {
                                cookTemp.Domain = strHost;
                            }
                        }
                        continue;
                    }
                }

                if (cookTemp.Path == string.Empty) {
                    cookTemp.Path = "/";
                }
                if (cookTemp.Domain == string.Empty) {
                    cookTemp.Domain = strHost;
                }
                cc.Add(cookTemp);
            }
            return cc;
        }
        /// <summary>
        /// Get QueryString of Uri 
        /// </summary>
        /// <param name="u">Uri</param>
        /// <param name="key">QueryString key</param>
        /// <returns>QueryString Value</returns>
        public static string GetQ(Uri u, string key) {
            string q = u.Query;
            int index = q.IndexOf(key+"=");
            int len = key.Length + 1;
            int index2 = q.IndexOf("&", index + len);
            string val = "";
            if (index2 == -1) {
                val = q.Substring(index + len, q.Length - index - len);
            }
            else {
                val = q.Substring(index + len, index2 - index - len);
            }
            return val;
        }
        /// <summary>
        /// Get part Content from HTML by apply prefix part and subfix part
        /// </summary>
        /// <param name="html">souce html</param>
        /// <param name="prefix">prefix</param>
        /// <param name="subfix">subfix</param>
        /// <returns>part content</returns>
        public static string Resove(string html, string prefix, string subfix) {
            int inl = html.IndexOf(prefix);
            if (inl == -1) {
                return null;
            }
            inl += prefix.Length;
            int inl2 = html.IndexOf(subfix, inl);
            var s = html.Substring(inl, inl2 - inl);
            return s;
        }
        public static string ResoveReverse(string html, string subfix, string prefix) {
            int inl = html.IndexOf(subfix);
            if (inl == -1) {
                return null;
            }
            string subString = html.Substring(0, inl);
            int inl2 = subString.LastIndexOf(prefix);
            if (inl2 == -1) {
                return null;
            }
            var s = subString.Substring(inl2 + prefix.Length, subString.Length - inl2-prefix.Length);
            return s;
        }
        public static  List<string> ResoveList(string html, string prefix, string subfix) {
            List<string> list = new List<string>();
            int index = prefix.Length * -1;
            do {
                index = html.IndexOf(prefix, index + prefix.Length);
                if (index == -1) {
                    break;
                }
                index += prefix.Length;
                int index4 = html.IndexOf(subfix, index);
                string s78 = html.Substring(index, index4 - index);
                list.Add(s78);
            }
            while (index > -1);
            return list;
        }
        #endregion
    }
}
